using AutoMapper;
using Matrix.Configuration;
using Matrix.Configuration.DTOs;

namespace Matrix.Configuration.Application
{
    /// <summary>
    /// 配置模块AutoMapper配置
    /// </summary>
    public class ConfigurationAutoMapperProfile : Profile
    {
        public ConfigurationAutoMapperProfile()
        {
            // 实体到DTO映射
            CreateMap<ConfigurationItem, ConfigurationItemDto>()
                .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
                .ForMember(dest => dest.Namespace, opt => opt.MapFrom(src => src.Namespace))
                .ForMember(dest => dest.Key, opt => opt.MapFrom(src => src.Key))
                .ForMember(dest => dest.Value, opt => opt.MapFrom(src => src.Value))
                .ForMember(dest => dest.Category, opt => opt.MapFrom(src => src.Category))
                .ForMember(dest => dest.DataType, opt => opt.MapFrom(src => src.DataType))
                .ForMember(dest => dest.Description, opt => opt.MapFrom(src => src.Description))
                .ForMember(dest => dest.Version, opt => opt.MapFrom(src => src.Version))
                .ForMember(dest => dest.TenantId, opt => opt.MapFrom(src => src.TenantId))
                .ForMember(dest => dest.CreationTime, opt => opt.MapFrom(src => src.CreationTime))
                .ForMember(dest => dest.LastModificationTime, opt => opt.MapFrom(src => src.LastModificationTime));

            // 创建DTO到实体映射
            CreateMap<CreateConfigurationItemDto, ConfigurationItem>()
                .ConstructUsing(src => new ConfigurationItem(
                    Guid.NewGuid(),
                    src.Namespace,
                    src.Key,
                    src.Value,
                    src.DataType,
                    src.Category ?? string.Empty,
                    src.Description))
                .ForAllMembers(opts => opts.Condition((src, dest, srcMember) => srcMember != null));

            // 更新DTO到实体映射 - 完全重写以避免字段交叉覆盖
            CreateMap<UpdateConfigurationItemDto, ConfigurationItem>()
                // 只映射明确提供且非空/空字符串的字段
                .ForMember(dest => dest.Value, opt => {
                    opt.Condition((src, dest, srcMember) => !string.IsNullOrEmpty(src.Value));
                    opt.MapFrom(src => src.Value);
                })
                .ForMember(dest => dest.Category, opt => {
                    opt.Condition((src, dest, srcMember) => !string.IsNullOrEmpty(src.Category));
                    opt.MapFrom(src => src.Category);
                })
                .ForMember(dest => dest.Description, opt => {
                    opt.Condition((src, dest, srcMember) => !string.IsNullOrEmpty(src.Description));
                    opt.MapFrom(src => src.Description);
                })
                .ForMember(dest => dest.DataType, opt => {
                    opt.Condition((src, dest, srcMember) => !string.IsNullOrEmpty(src.DataType));
                    opt.MapFrom(src => src.DataType);
                })
                // 对所有成员应用条件，确保只有非空值才会被映射
                .ForAllMembers(opts => opts.Condition((src, dest, srcMember) => {
                    // 检查源属性是否为非空且非空字符串
                    if (srcMember == null) return false;
                    if (srcMember is string stringValue) return !string.IsNullOrEmpty(stringValue);
                    return true;
                }));

            // 批量操作DTO到实体映射
            CreateMap<BatchConfigurationItemDto, ConfigurationItem>()
                .ConstructUsing(src => new ConfigurationItem(
                    Guid.NewGuid(),
                    src.Namespace,
                    src.Key,
                    src.Value,
                    src.DataType,
                    src.Category ?? string.Empty,
                    src.Description));
        }
    }
}